﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;

public abstract class GpuHudEntityBase : IGpuHudEntity, IDisposable
{
    #region 运行时管理部分
    public GpuHudEntityBase preEntity;
    public GpuHudEntityBase nextEntity;
    #endregion
    protected GpuHudEntityBase()
    {
        assetLogicIdx = -1;
    }
    public bool isLocalizationDirty;
    protected bool isInitialize = false;
    public bool isRunning = false;
    public bool IsInitialize
    {
        get
        {
            return isInitialize;
        }
    }

    protected GpuHudAsset m_gpuHudAsset;
    public GpuHudAsset GpuHudAsset
    {
        get
        {
            return m_gpuHudAsset;
        }
    }

    public bool removeDirty = false;

    //在同一种资源列表里的下标
    private int assetLogicIdx = -1;

    public int AssetLogicIdx
    {
        get
        {
            return assetLogicIdx;
        }
    }
    
    /// <summary>
    /// gpuHud数据管理器
    /// </summary>
    protected GpuHudDataAccessor m_gpuHudAccessor;
    public GpuHudDataAccessor GpuHudAccessor
    {
        get { return m_gpuHudAccessor; }
    }

    private float m_startTimestamp;
    public float StartTimestamp
    {
        get { return m_startTimestamp; }
        set { m_startTimestamp = value; }
    }

    public abstract GpuHudEntityType GetEntityType();

    public virtual void OnDispose()
    {
        m_gpuHudAsset.ReleaseEntityRef(this);
        //if (removeDirty) return; 
        GpuHudFacade facade = GpuHudFacade.GpuFacade;
        isRunning = false;
        facade.UnRegisterEntityReference(this);
        m_gpuHudAccessor?.OnDispose();
        m_gpuHudAsset?.OnDispose();
        GpuHudFacade.GpuFacade.entityCount--;
    }

    public void OnInit(GpuHudAsset asset)
    {
        isLocalizationDirty = false;
        GpuHudFacade facade = GpuHudFacade.GpuFacade;
        removeDirty = false;
        m_gpuHudAsset = asset;
        if (m_gpuHudAsset == null) return;
        asset.OnUse();
        if(assetLogicIdx == -1)
        {
            assetLogicIdx = asset.RegisterEntityRef(this);
        }
        m_gpuHudAccessor = new GpuHudDataAccessor(m_gpuHudAsset);
        m_gpuHudAccessor.gpuHudBaseEntity = this;
        facade?.RegisterEntityReference(this);
        isRunning = true;
        GpuHudFacade.GpuFacade.entityCount++;
        LateInit();
    }
    protected abstract void LateInit();
    protected abstract void PrePlay();

    public void OnPlay()
    {
        if (m_gpuHudAccessor == null) return;
        StartTimestamp = Time.time;

        PrePlay();

        m_gpuHudAccessor.RebuildShaderData();
        m_gpuHudAccessor.SetOnScreen();

        LatePlay();

        //必须设置
        isInitialize = true;
    }

    /// <summary>
    /// Play后操作
    /// Play中存在分配内存-重构数据的功能
    /// </summary>
    protected abstract void LatePlay();

    public void OnLateUpdate() {
        if (m_gpuHudAccessor == null) return;
        if (removeDirty) return;

        LateUpdate();
    }

    protected abstract void LateUpdate();

    #region 池化接口
    protected abstract void PreBackPool();
    public void BackPool()
    {
        GpuHudFacade facade = GpuHudFacade.GpuFacade;
        m_gpuHudAccessor.SetOffScreen();
        isRunning = false;
        facade.UnRegisterEntityReference(this);
        PreBackPool();
    }

    public void OutPool()
    {
        GpuHudFacade facade = GpuHudFacade.GpuFacade;
        LateOutPool();
        isInitialize = false;
        removeDirty = false;
        facade.RegisterEntityReference(this);
        isRunning = true;
    }

    protected abstract void LateOutPool();

    /// <summary>
    /// 池坍缩时触发的销毁
    /// </summary>
    public void OnShrink()
    {
        OnPreShrink();
        OnDispose();
    }

    protected virtual void OnPreShrink() { }
    #endregion

    public void Dispose()
    {
        m_gpuHudAccessor?.OnDispose();
        m_gpuHudAsset?.OnDispose();
        m_gpuHudAccessor = null;
    }
    /// <summary>
    /// 有些资源会被GpuHudFacade引用,也要Dispose
    /// </summary>
    public void TryDispose()
    {
        m_gpuHudAccessor?.OnDispose();
    }
}
